
#ifndef __femlib_exceptions_h__
#define __femlib_exceptions_h__

#include "stacktrace.hh"

#ifdef NDEBUG
  #define femlib_assert(x, msg) ((void)0)
#else
  #include <fstream>
  #include <iostream>
  #include <stdexcept>

  #define femlib_assert(x, msg)         \
  if (!(x))                              \
  {                                      \
    std::cout                            \
      << "ERROR!! Assertion "            \
      <<  std::string (#x)               \
      <<  " failed on line "             \
      <<  (__LINE__)                     \
      <<  " in file "                    \
      <<  __FILE__                       \
      << std::endl << std::endl;         \
    std::cout                            \
      << "User error message:"           \
      << std::endl                       \
      << msg                             \
      << std::endl;                      \
    print_stacktrace(std::cout);         \
    std::ofstream f("assert_out.txt");   \
    f                                    \
      << "ERROR!! Assertion "            \
      <<  std::string (#x)               \
      <<  " failed on line "             \
      <<  (__LINE__)                     \
      <<  " in file "                    \
      <<  __FILE__                       \
      << std::endl << std::endl;         \
    f                                    \
      << "User error message:"           \
      << std::endl                       \
      << msg                             \
      << std::endl;                      \
    f.close();                           \
      throw std::logic_error(            \
        "Assertion failed");             \
  }

#endif

#endif // __femlib_exceptions_h__
